import axios from 'axios';
import DB from './DB';

class Down extends DB {
	constructor() {
		super();
		this.times = 1;
		this.isLast = false;
		this.startSize = 0;
		this.nextSize = 0;
		this.fileType = '';
		this.initDownloadDB();
	}

	async initDownloadDB () {
		await this.openDB();
	}

	async getDataById (id) {
		const resData = await this.getDbDataById(id);
		return resData;
	}

	async deleteFile (id) {
		const resp = await this.del(id);
		return resp;
	}

	async saveFile (id) {
		const file = await this.getDataById(id);
		console.log(file);
		if (file.statusCode === 200) {
			console.log('文件分片下载完成，开始合并文件。');
			const item = file.data;
			const { fileName, fileBlobs } = item;
			const data = new Blob(fileBlobs, { type: this.fileType });
			const elink = document.createElement('a');
			elink.download = fileName;
			elink.style.display = 'none';
			elink.href = window.URL.createObjectURL(data);
			document.body.appendChild(elink);
			elink.click();
			window.URL.revokeObjectURL(elink.href); // 释放URL对象
			document.body.removeChild(elink);
			// 自动删除文件
			return setTimeout(() => {
				this.deleteFile(item.id);
			}, 3000);
		}
		this.times = 1;
		this.isLast = false;
		this.startSize = 0;
		this.nextSize = 0;
		console.log('获取文件信息失败');
		return false;
	}

	finishDownload (params) {
		if (params.url !== '') {
			axios(params);
		}
	}

	/**
	 * 下载方法
	 * @param {下载文件参数} fileData 包含参数：url 分片下载地址，perSize 分片大小， total 文件总大小，id 下载id， fileName 下载文件保存名称
	 * @returns
	 */
	async download (fileData, onError, onSuccess) {
		console.log(`分片下载开始，第${this.times}片下载开始。`);
		const { url, psize, fileType, id, total, fileName = `${new Date().getTime()}` } = fileData;
		this.fileType = fileType;
		this.nextSize = psize;
		const insertData = {
			id,
			fileName,
			size: 0,
			total,
			fileBlobs: []
		};

		const res = await this.getDataById(id);
		if (res.statusCode !== 200) {
			return {
				statusCode: 200,
				message: '本地indexDB查询出错'
			};
		}

		const perSize = psize || 10 * 1024 * 1024; // 此处分片大小必须按字节数分片，不能为任意整数
		const { data: file } = res;
		let nextSize = total - this.startSize + this.nextSize - 1 <= 1024 ? total - this.startSize : this.startSize + this.nextSize - 1;
		let headers = {
			Range: `bytes=${this.startSize}-${this.startSize + this.nextSize - 1 >= total ? total : nextSize}`
		};
		console.log('分片下载参数：', headers, this.startSize, nextSize, total, this.isLast);
		return axios({
			method: 'GET',
			url,
			responseType: 'blob',
			headers
		})
			.then(async request => {
				const { status, data: responseData } = request;
				if (status === 206 && responseData) {
					console.log(`分片下载开始，第${this.times}片下载完成。`, responseData);
					this.times++;
					this.startSize += perSize;
					this.isLast = this.startSize >= total;
					let textArray = responseData;
					let blobs = [];
					blobs = [new Blob([textArray], { type: fileType })];
					// 当前下载的文件size
					let size = 0;
					blobs.forEach(bitem => {
						console.log(bitem);
						size += bitem.size;
					});
					let fileRes = null;
					if (file) {
						size += file.size;
						fileRes = await this.update({
							...insertData,
							size,
							fileBlobs: [...file.fileBlobs, ...blobs]
						});
					} else {
						fileRes = await this.insert({
							...insertData,
							size,
							fileBlobs: [...blobs]
						});
					}
					console.log(this.isLast);
					if (fileRes.statusCode === 200 && !this.isLast) {
						// 如果没有下载完成
						this.download({ ...fileData, size }, onError, onSuccess);
					} else if (this.isLast) {
						// 如果最后一个文件下载完毕，自动保存文件
						const iRes = await this.update({
							...insertData,
							size,
							fileBlobs: file ? [...file.fileBlobs, ...blobs] : [...blobs]
						});
						if (iRes) {
							this.saveFile(id);
						}
						onSuccess && onSuccess('ok');
					}
				} else {
					this.deleteFile(insertData.id);
					onError && onError('error');
				}
			})
			.catch(err => {
				this.deleteFile(insertData.id);
				console.log('download err', err);
				onError && onError(err);
			});
	}
}

export default new Down();
